package com.shanjupay.transaction.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shanjupay.common.cache.Cache;
import com.shanjupay.common.domain.BusinessException;
import com.shanjupay.common.domain.CommonErrorCode;
import com.shanjupay.common.util.RedisUtil;
import com.shanjupay.transaction.api.PayChannelService;
import com.shanjupay.transaction.api.dto.PayChannelDTO;
import com.shanjupay.transaction.api.dto.PayChannelParamDTO;
import com.shanjupay.transaction.api.dto.PlatformChannelDTO;
import com.shanjupay.transaction.convert.PayChannelParamConvert;
import com.shanjupay.transaction.convert.PlatformChannelConvert;
import com.shanjupay.transaction.entity.AppPlatformChannel;
import com.shanjupay.transaction.entity.PayChannelParam;
import com.shanjupay.transaction.entity.PlatformChannel;
import com.shanjupay.transaction.mapper.AppPlatformChannelMapper;
import com.shanjupay.transaction.mapper.PayChannelParamMapper;
import com.shanjupay.transaction.mapper.PlatformChannelMapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * TODO
 *
 * @Description
 * @Author zhangbing
 * @Date 2024/5/20 15:35
 **/
@Service
public class PayChannelServiceImpl implements PayChannelService {

    @Autowired
    private PlatformChannelMapper platformChannelMapper;
    @Autowired
    private AppPlatformChannelMapper appPlatformChannelMapper;

    @Autowired
    private PayChannelParamMapper payChannelParamMapper;

    @Resource
    private Cache cache;


    //获取平台服务类型
    @Override
    public List<PlatformChannelDTO> queryPlatformChannel() throws BusinessException {
        List<PlatformChannel> platformChannels = platformChannelMapper.selectList(null);
        //转换
        List<PlatformChannelDTO> listdto = PlatformChannelConvert.INSTANCE.listentity2listdto(platformChannels);
        return listdto;
    }

    /**
     * 为app绑定平台服务类型
     * @param appId 应用id
     * @param platformChannelCodes 平台服务类型列表
     */
    @Override
    public void bindPlatformChannelForApp(String appId, String platformChannelCodes) throws BusinessException {
        //根据appID 和平台服务类型code查询 platform_channel
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(new
                LambdaQueryWrapper<AppPlatformChannel>()
                .eq(AppPlatformChannel::getAppId, appId)
                .eq(AppPlatformChannel::getPlatformChannel, platformChannelCodes));

        //如果没有帮绑定 则绑定
        if(appPlatformChannel==null){
           //绑定
             appPlatformChannel = new AppPlatformChannel();
            appPlatformChannel.setAppId(appId);
            appPlatformChannel.setPlatformChannel(platformChannelCodes);
            appPlatformChannelMapper.insert(appPlatformChannel);
        }

    }

    @Override
    public int queryAppBindPlatformChannel(String appId, String platformChannel) throws BusinessException {
        Integer count = appPlatformChannelMapper.selectCount(new QueryWrapper<AppPlatformChannel>()
                .lambda()
                .eq(AppPlatformChannel::getAppId, appId)
                .eq(AppPlatformChannel::getPlatformChannel, platformChannel));
                if(count >0){
                   return 1;
                }else {
                    return 0;
                }
    }

    /**
     * 通过服务绑定类型的code查询支付渠道列表
     * @param platformChannelCode
     * @return
     * @throws BusinessException
     */
    @Override
    public List<PayChannelDTO> queryPayChannelByPlatFormChannel(String platformChannelCode) throws BusinessException {

        return platformChannelMapper.selectPayChannelByPlatformChannel(platformChannelCode);
    }

    //保存支付渠道参数配置
    @Override
    public void savePayChannelParam(PayChannelParamDTO payChannelParamDTO) throws BusinessException {

        if(payChannelParamDTO == null || payChannelParamDTO.getChannelName() == null || payChannelParamDTO.getParam()== null){
            throw new BusinessException(CommonErrorCode.E_300009);
        }
        //根据应用、服务类型、支付渠道查询一条记录
        //根据应用、服务类型查询应用与服务类型的绑定id
        Long appPlatformChannelId = selectIdByAppPlatformChannel(payChannelParamDTO.getAppId(), payChannelParamDTO.getPlatformChannelCode());
        if(appPlatformChannelId == null){
            throw new BusinessException(CommonErrorCode.E_300010);
        }

        //根据应用与服务类型绑定id和支付渠道查询参数信息
        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(new
                LambdaQueryWrapper<PayChannelParam>()
                .eq(PayChannelParam::getAppPlatformChannelId,
                        appPlatformChannelId)
                .eq(PayChannelParam::getPayChannel, payChannelParamDTO.getPayChannel()));
        //更新已有配置
        if (payChannelParam!=null){
            payChannelParam.setChannelName(payChannelParamDTO.getChannelName());
            payChannelParam.setParam(payChannelParamDTO.getParam());
            payChannelParamMapper.updateById(payChannelParam);
        }else{
            //添加新配置
            PayChannelParam entity =
                    PayChannelParamConvert.INSTANCE.dto2entity(payChannelParamDTO);
            entity.setId(null);
            //应用与服务类型绑定id
            entity.setAppPlatformChannelId(appPlatformChannelId);
            payChannelParamMapper.insert(entity);
            //更新缓存
            updateCache(payChannelParamDTO.getAppId(),payChannelParamDTO.getPlatformChannelCode());
            System.out.println(entity);
        }

    }

    //查询支付参数列表
    @Override
    public List<PayChannelParamDTO> queryPayChannelParambyAppIdPlatformChannel(String appId, String platformChannel) {

        //从缓存中查询 通过key
        String redisKey = RedisUtil.keyBuilder(appId, platformChannel);
        Boolean exists = cache.exists(redisKey);
        if(exists){//存在
            //从redis中获取key对应的value值
            String value = cache.get(redisKey);
            //将value转成对象
            List<PayChannelParamDTO> paramDTOS = JSONObject.parseArray(value,
                    PayChannelParamDTO.class);
            return paramDTOS;
        }
        //判断是否有缓存
       //根据服务id和服务类型
        Long appPlatformChannelId = selectIdByAppPlatformChannel(appId, platformChannel);
        //根据appPlatformChannelId和platformChannel查询
        List<PayChannelParam> selectList = payChannelParamMapper.selectList(new LambdaQueryWrapper<PayChannelParam>().eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId));
        updateCache(appId,platformChannel);
        return PayChannelParamConvert.INSTANCE.listentity2listdto(selectList);

    }

    /**
     * 根据appid和服务类型查询应用与服务类型绑定id
     * @param appId
     * @param platformChannelCode
     * @return
     */
    private Long selectIdByAppPlatformChannel(String appId,String platformChannelCode){
        //根据appid和服务类型查询应用与服务类型绑定id
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(new
                LambdaQueryWrapper<AppPlatformChannel>().eq(AppPlatformChannel::getAppId, appId)
                .eq(AppPlatformChannel::getPlatformChannel, platformChannelCode));
        if(appPlatformChannel!=null){
            return appPlatformChannel.getId();
        }
        return null;
    }
    //查询支付参数
    @Override
    public PayChannelParamDTO queryParamByAppIdPlatformChannelAndpayChannel(String appId, String platformChannel, String payChannel) {
        //Long appPlatformChannelId = selectIdByAppPlatformChannel(appId, platformChannel);
        //PayChannelParam payChannelParam = payChannelParamMapper.selectOne(new LambdaQueryWrapper<PayChannelParam>().eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId).eq(PayChannelParam::getPayChannel, payChannel));
        List<PayChannelParamDTO> payChannelParamDTOS = queryPayChannelParambyAppIdPlatformChannel(appId, platformChannel);
        for(PayChannelParamDTO payChannelParamDTO:payChannelParamDTOS){
            if(payChannelParamDTO.getPayChannel().equals(payChannel)){
                return payChannelParamDTO;
            }
        }
        return null;
    }

    public List<PayChannelParamDTO> selPayChannelParam(String appId,String platformChannel){
        //查出应用id和服务类型代码在app_platform_channel主键
        Long appPlatformChannelId = selectIdByAppPlatformChannel(appId,platformChannel);
        //根据appPlatformChannelId从pay_channel_param查询所有支付参数
        List<PayChannelParam> payChannelParams = payChannelParamMapper.selectList(new
                LambdaQueryWrapper<PayChannelParam>().eq(PayChannelParam::getAppPlatformChannelId,
                appPlatformChannelId));
        List<PayChannelParamDTO> paramDTOS =
                PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParams);
        return paramDTOS;
    }

    //缓存方法
    public void updateCache(String appId,String platformChannel){
        //处理缓存
        //1.构建key
        String redisKey = RedisUtil.keyBuilder(appId, platformChannel);
        //2.检查key是否存在
        Boolean exists = cache.exists(redisKey);
        if(exists){//存在
            //删除原有缓存
            cache.del(redisKey);
        }
        //3.从数据库中 根据appId platformChannel查询，重新存入缓存中
        List<PayChannelParamDTO> paramDTOS = selPayChannelParam(appId, platformChannel);
        // List<PayChannelParamDTO> paramDTOS = queryPayChannelParambyAppIdPlatformChannel(appId, platformChannel);
        if(paramDTOS !=null){
            //存入缓存
            cache.set(redisKey,JSON.toJSON(paramDTOS).toString());
        }
    }

}
